package com.tianci.appstore.controller.manager;

import android.os.Environment;
import android.os.RemoteException;
import android.os.StatFs;

import com.coocaa.x.framework.utils.LiteURI;
import com.coocaa.x.framework.utils.LogUtils;
import com.coocaa.x.service.XServiceManager;
import com.coocaa.x.service.litecontent.LiteContentServiceConnecter;
import com.coocaa.x.service.litecontent.data.apps.com_coocaa_app.AppData;
import com.coocaa.x.service.litecontent.data.apps.com_coocaa_app.RP_Installed_Apps;
import com.coocaa.x.service.litepm.aidl.ILitePMClearCacheListener;
import com.coocaa.x.service.litepm.data.AppInfo;
import com.skyworth.framework.skysdk.app.SkyAppService;
import com.skyworth.framework.skysdk.app.SkyAppService.PackageMoveLocation;
import com.skyworth.framework.skysdk.app.SkyAppService.PackageSizeListener;
import com.tianci.appstore.controller.AppStoreBaseController;
import com.tianci.appstore.ui.data.SkyListAppData;
import com.tianci.appstore.ui.data.SkyListAppData.ListType;
import com.tianci.appstore.ui.list.clearcache.OnClearCacheStateListener;
import com.tianci.appstore.utils.ExternalStorageMonitor;
import com.tianci.appstore.utils.ExternalStorageMonitor.ExternalStorageMonitorListener;
import com.tianci.appstore.utils.SkyConstants;
import com.tianci.appstore.utils.Tools;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ClearCacheManagerController extends AppStoreBaseController implements
        ExternalStorageMonitorListener {

    private static ClearCacheManagerController managerController = null;
    private List<SkyListAppData> mAppDatas = null;
    private List<SkyListAppData> mWaitClearList = new ArrayList<SkyListAppData>();
    private OnClearCacheStateListener mClearCacheStateListener = null;
    private float mCacheSize = 0.0f;
    private float mClearCache = 0.0f;
    private int mAppSize = 0;

    public static ClearCacheManagerController getInstance() {
        if (null == managerController)
            managerController = new ClearCacheManagerController();
        return managerController;
    }

    public ClearCacheManagerController() {
        mAppDatas = new ArrayList<SkyListAppData>();
    }

    public void registExternalStorageChangedListener() {
        ExternalStorageMonitor.setListener(this);
    }

    public void setClearCacheStateListener(OnClearCacheStateListener listener) {
        this.mClearCacheStateListener = listener;
    }

    public float getTotalCacheSize() {
        return mCacheSize;
    }

    public float getInstalledAppSpaceSize() {
        if (mAppDatas != null && mAppDatas.size() > 0) {
            float allSize = 0;
            long size = 0;
            for (SkyListAppData data : mAppDatas) {
                long appSize = data.getSize();
                size += appSize;
                allSize = (float) size / SkyConstants.KTOM;
                allSize = Tools.fixFloat(allSize);
            }
            return allSize;
        } else {
            return 0.0f;
        }
    }

    public int getInstallAppSize(PackageMoveLocation location) {
        return mAppDatas.size();
    }

    public void clearCacheAppList(List<SkyListAppData> appDatas) {
        LogUtils.d("wait to clear cache size is " + appDatas.size());
        mFailedList.clear();
        mWaitClearList.addAll(appDatas);
        clearAppCache(mWaitClearList.remove(0));
    }

    public void clearAllCache() {
        mWaitClearList.addAll(mAppDatas);
        if (mWaitClearList.size() > 0) {
            clearAppCache(mWaitClearList.remove(0));
        }
    }

    private void clearAppCache(SkyListAppData data) {
        LogUtils.d("begin clear " + data.getPkgName() + " cache");
        mTempAppData = data;
        try {
            XServiceManager.getLitePMService().clearCache(data.getPkgName(), clearCacheStub);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private List<SkyListAppData> formData(List<AppInfo> list) {
        List<SkyListAppData> ret = new ArrayList<SkyListAppData>();
        for (AppInfo info : list) {
            SkyListAppData appInfo = new SkyListAppData(ListType.LOCAL_APP_LIST, "", info.appName,
                    "", info.pkgName);
            appInfo.setVersionName(String.valueOf(info.versionCode));
            appInfo.setMainActivity(info.mainActivity);
            long size = info.size / SkyConstants.BTOK;
            appInfo.setSize(size);
            float size2 = (float) size / SkyConstants.KTOM;
            if (size2 > 1.0f) {
                size2 = Tools.fixFloat(size2);
                appInfo.setShowInfo(String.valueOf(size2) + "MB");
            } else {
                appInfo.setShowInfo(String.valueOf(size) + "KB");
            }
            ret.add(appInfo);
        }
        return ret;
    }

    public void getLocalApps() {
        // final List<SkyListAppData> appDatas = AppDataProvider.getInstance().getLocalData()
        // .getInstalledAllApp();

        LiteURI uri = LiteURI.create("apps://com.coocaa.app/installed_apps");
        uri.addParams("filter", "mine");
        String json = null;
        try {
            json = LiteContentServiceConnecter.getService().call(uri.toString());
        } catch (RemoteException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        List<AppInfo> appinfos = new ArrayList<AppInfo>();
        if (json != null) {
            RP_Installed_Apps rp = RP_Installed_Apps.parseJObject(json, RP_Installed_Apps.class);
            List<AppData> appdatas = rp.resource.resource_items;
            for (AppData appdata : appdatas) {
                if (!appdata.info.pkgName.equals("com.tianci.appstore"))
                    appinfos.add(appdata.info);
            }
        }

        final List<SkyListAppData> appDatas = formData(appinfos);
        mCacheSize = 0.0f;
        mAppSize = 0;
        mAppDatas.clear();
        if (appDatas != null && appDatas.size() > 0) {
            for (final SkyListAppData data : appDatas) {
                SkyAppService.getSkyAppService(mContext).getAppSize(data.getPkgName(),
                        new PackageSizeListener() {

                            @Override
                            public void onPackageSize(String pname, long size) {
                                // TODO Auto-generated method stub

                            }

                            @Override
                            public void onPackageDataSize(String pname, long size) {
                                // TODO Auto-generated method stub

                            }

                            @Override
                            public void onPackageCachedSize(String pname, long size) {
                                LogUtils.d("the " + pname + " cache size is " + size);
                                mAppSize++;
                                float tempSize = size / SkyConstants.BTOK;
                                data.setSize((long) tempSize);
                                if (!(tempSize == 0 || tempSize == 12)) {
                                    mCacheSize += tempSize;
                                    if (tempSize > 1024) {
                                        data.setShowInfo((float) Math
                                                .round((tempSize / SkyConstants.KTOM) * 10)
                                                / 10
                                                + "MB");
                                    } else {
                                        data.setShowInfo(tempSize + "KB");
                                    }
                                    mAppDatas.add(data);
                                }
                                if (mAppSize == appDatas.size() && mClearCacheStateListener != null) {
                                    mClearCacheStateListener.appSizeChange(mAppDatas);
                                    LogUtils.d("all cache size is " + mCacheSize);
                                    try {
                                        Collections.sort(mAppDatas,
                                                new Comparator<SkyListAppData>() {
                                                    public int compare(SkyListAppData arg0,
                                                                       SkyListAppData arg1) {
                                                        return arg0.getSize() > arg1.getSize() ? -1
                                                                : 1;
                                                    }
                                                });
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                    mClearCacheStateListener.refreshCacheData(mAppDatas.size(),
                                            mCacheSize);
                                }
                            }
                        });
            }
        } else {
            if (mClearCacheStateListener != null) {
                mClearCacheStateListener.refreshCacheData(mAppDatas.size(), mCacheSize);
            }
        }
    }

    // 获取系统总内存
    public float getTotalInternalMemorySize() {
        File path = Environment.getDataDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSize();
        long totalBlocks = stat.getBlockCount();
        float size = (float) (totalBlocks * blockSize) / SkyConstants.BTOM;
        size = Tools.fixFloat(size);
        return size;
    }

    // 获取系统可用的总内存
    public float getAvailableInternalMemorySize() {
        File path = Environment.getDataDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSize();
        long availableBlocks = stat.getAvailableBlocks();
        float size = (float) (availableBlocks * blockSize) / SkyConstants.BTOM;
        size = Tools.fixFloat(size);
        return size;
    }

    @Override
    public void destroy() {
        mCacheSize = 0.0f;
        mAppDatas.clear();
        mAppSize = 0;
        ExternalStorageMonitor.clearListener(this);
        managerController = null;
    }

    private ILitePMClearCacheListener.Stub clearCacheStub = new ILitePMClearCacheListener.Stub() {

        @Override
        public void onPackageCacheClear(String packageName, boolean success) throws RemoteException {
            // TODO Auto-generated method stub
            LogUtils.d(packageName + " move " + success);
            if (!success) {
                mFailedList.add(mTempAppData);
            } else {
                mClearCache += mTempAppData.getSize();
            }
            if (mWaitClearList.size() > 0) {
                clearAppCache(mWaitClearList.remove(0));
            } else {
                getLocalApps();
                mClearCacheStateListener.clearCache(mFailedList, mClearCache);
            }
        }
    };

    @Override
    public void onExternalStorageChanged(boolean bMounted) {
        getLocalApps();
    }
}
